package org.chartsy.uo;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import org.chartsy.main.ChartFrame;
import org.chartsy.main.chart.Indicator;
import org.chartsy.main.data.DataItem;
import org.chartsy.main.data.Dataset;
import org.chartsy.main.utils.DefaultPainter;
import org.chartsy.main.utils.Range;
import org.chartsy.main.utils.SerialVersion;
import org.chartsy.main.utils.StrokeGenerator;
import org.openide.nodes.AbstractNode;
/**
*
* @author viorel.gheba
*/
public class UltimateOscillator
extends Indicator
{
private static final long serialVersionUID = SerialVersion.APPVERSION;
public static final String UO = "UO";
private IndicatorProperties properties;
public UltimateOscillator() {
super();
properties = new IndicatorProperties();
}
public String getName() {return "Ultimate Oscillator"; }
public String getLabel(){ return properties.getLabel(); }
public String getPaintedLabel(ChartFrame cf){ return getLabel(); }
public Indicator newInstance() {return new UltimateOscillator(); }
@Override
public LinkedHashMap getHTML(ChartFrame cf, int i) {
LinkedHashMap ht = new LinkedHashMap();
DecimalFormat df = new DecimalFormat("#,##0.00");
double[] values = getValues(cf, i);
String[] labels = {"UO:"};
ht.put(getLabel(), " ");
if (values.length > 0) {
Color[] colors = getColors();
for (int j = 0; j < values.length; j++) {
ht.put(getFontHTML(colors[j], labels[j]),
getFontHTML(colors[j], df.format(values[j])));
}
}
return ht;
}
@Override
public Range getRange(ChartFrame cf){ return new Range(0, 100); }
public void paint(Graphics2D g, ChartFrame cf, Rectangle bounds)
{
Dataset d = visibleDataset(cf, UO);
if (d != null)
{
if (maximized)
{
Range range = getRange(cf);
DefaultPainter.line(g, cf, range, bounds, d, properties.getColor(), properties.getStroke()); // paint line
}
}
}
public void calculate() {
Dataset initial = getDataset();
if (initial != null && !initial.isEmpty()) {
Dataset d = getDataset(initial);
addDataset(UO, d);
}
}
public boolean hasZeroLine(){ return false; }
public boolean getZeroLineVisibility(){ return false; }
public Color getZeroLineColor(){ return null; }
public Stroke getZeroLineStroke(){ return null; }
public boolean hasDelimiters(){ return true; }
public boolean getDelimitersVisibility(){ return true; }
public double[] getDelimitersValues()
{ return new double[] {30.0d, 50.0d, 70.0d}; }
public Color getDelimitersColor(){ return properties.getDelimiterColor(); }
public Stroke getDelimitersStroke(){ return properties.getDelimiterLineStroke(); }
public Color[] getColors() { return new Color[] {properties.getColor()}; }
public double[] getValues(ChartFrame cf) {
Dataset d = visibleDataset(cf, UO);
if (d != null) {
return new double[] {d.getLastClose()};
}
return new double[] {};
}
public double[] getValues(ChartFrame cf, int i) {
Dataset d = visibleDataset(cf, UO);
if (d != null) {
return new double[] {d.getCloseAt(i)};
}
return new double[] {};
}
public boolean getMarkerVisibility() {return properties.getMarker(); }
public AbstractNode getNode() {return new IndicatorNode(properties); }
@Override
public Double[] getPriceValues(ChartFrame cf)
{ return new Double[] {new Double(10), new Double(30), new Double(50), new Double(70), new Double(90)}; }
private Dataset getDataset(final Dataset initial) {
int fast = properties.getFast();
int inter = properties.getIntermediate();
int slow = properties.getSlow();
int count = initial.getItemsCount();
Dataset d = Dataset.EMPTY(count);
double temp, sbFast, srFast, sbInter, srInter, sbSlow, srSlow, rFast, rInter, rSlow;
for (int i = slow; i < count; i++) {
sbFast = 0;
srFast = 0;
for (int j = 0; j < fast; j++) {
if (initial.getCloseAt(i-j-1) < initial.getLowAt(i-j))
sbFast += initial.getCloseAt(i-j) - initial.getCloseAt(i-j-1);
else
sbFast += initial.getCloseAt(i-j) - initial.getLowAt(i-j);
if ((initial.getHighAt(i-j) - initial.getLowAt(i-j)) > (initial.getHighAt(i-j) - initial.getCloseAt(i-j-1)))
temp = initial.getHighAt(i-j) - initial.getLowAt(i-j);
else
temp = initial.getHighAt(i-j) - initial.getCloseAt(i-j-1);
if (temp > (initial.getCloseAt(i-j-1) - initial.getLowAt(i-j)))
rFast = temp;
else
rFast = initial.getCloseAt(i-j-1) - initial.getLowAt(i-j);
srFast += rFast;
}
sbInter = sbFast;
srInter = srFast;
for (int j = fast; j < inter; j++) {
if (initial.getCloseAt(i-j-1) < initial.getLowAt(i-j))
sbInter += initial.getCloseAt(i-j) - initial.getCloseAt(i-j-1);
else
sbInter += initial.getCloseAt(i-j) - initial.getLowAt(i-j);
if ((initial.getHighAt(i-j) - initial.getLowAt(i-j)) > (initial.getHighAt(i-j) - initial.getCloseAt(i-j-1)))
temp = initial.getHighAt(i-j) - initial.getLowAt(i-j);
else
temp = initial.getHighAt(i-j) - initial.getCloseAt(i-j-1);
if (temp > (initial.getCloseAt(i-j-1) - initial.getLowAt(i-j)))
rInter = temp;
else
rInter = initial.getCloseAt(i-j-1) - initial.getLowAt(i-j);
srInter += rInter;
}
sbSlow = sbInter;
srSlow = srInter;
for (int j = inter; j < slow; j++) {
if (initial.getCloseAt(i-j-1) < initial.getLowAt(i-j))
sbSlow += initial.getCloseAt(i-j) - initial.getCloseAt(i-j-1);
else
sbSlow += initial.getCloseAt(i-j) - initial.getLowAt(i-j);
if ((initial.getHighAt(i-j) - initial.getLowAt(i-j)) > (initial.getHighAt(i-j) - initial.getCloseAt(i-j-1)))
temp = initial.getHighAt(i-j) - initial.getLowAt(i-j);
else
temp = initial.getHighAt(i-j) - initial.getCloseAt(i-j-1);
if (temp > (initial.getCloseAt(i-j-1) - initial.getLowAt(i-j)))
rSlow = temp;
else
rSlow = initial.getCloseAt(i-j-1) - initial.getLowAt(i-j);
srSlow += rSlow;
}
if (srFast != 0 && srInter != 0 && srSlow != 0)
d.setDataItem(i, new DataItem(initial.getTimeAt(i), (100d * (4*sbFast/srFast + 2*sbInter/srInter + sbSlow/srSlow) / 7d)));
}
return d;
}
}